import * as CryptoJS from 'crypto-js';

/**
 * 生成一个随机的盐值（salt）。
 * 盐值用于密码加密，以防止彩虹表攻击（rainbow table attack）。
 * 通过为每个密码添加一个唯一的盐值，可以显著提高密码的安全性。
 *
 * @returns {string} 一个随机生成的盐值，以 Base64 编码的字符串形式返回。
 */
export function makeSalt(): string {
  // 使用 CryptoJS 的 WordArray.random 方法生成一个长度为 16 字节（128 位）的随机字节数组。
  // 这个长度足够用于密码加密中的盐值。
  const randomBytes = CryptoJS.lib.WordArray.random(16);

  // 将生成的随机字节数组转换为 Base64 编码的字符串，便于存储和传输。
  return randomBytes.toString(CryptoJS.enc.Base64);
}

/**
 * 使用 PBKDF2 算法对秘密信息（如密码）进行加密。
 * PBKDF2 是一种基于密钥的密钥派生函数，通过多次迭代将密码和盐值结合，
 * 生成一个固定长度的密钥，用于安全存储或验证。
 *
 * @param {string} secret 需要加密的秘密信息，通常是用户的密码。
 * @param {string} salt 用于加密的盐值，通常由 makeSalt 函数生成。
 * @returns {string} 加密后的密钥，以 Base64 编码的字符串形式返回。
 */
export function encryptWithSalt(secret: string, salt: string): string {
  // 如果 secret 或 salt 为空，则直接返回空字符串，避免无效操作。
  if (!secret || !salt) return '';

  // 使用 CryptoJS 的 PBKDF2 方法对 secret 进行加密。
  // 参数说明：
  // - secret：需要加密的秘密信息。
  // - salt：盐值，用于增加密码的复杂性。
  // - keySize：生成的密钥长度，单位为字节。这里设置为 16 字节（128 位）。
  // - iterations：迭代次数，用于增加加密的复杂性。这里设置为 1000 次。
  const encrypted = CryptoJS.PBKDF2(secret, salt, {
    keySize: 16, // 生成 16 字节（128 位）的密钥
    iterations: 1000, // 迭代 1000 次，增加破解难度
  });

  // 将生成的密钥转换为 Base64 编码的字符串，便于存储和传输。
  return encrypted.toString(CryptoJS.enc.Base64);
}
